package com.bigdatastudio.auth.serverImpl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bigdatastudio.auth.mapper.AuthMapper;
import com.bigdatastudio.auth.server.IAuthService;
import com.bigdatastudio.auth.server.IRoleService;
import com.bigdatastudio.common.Exception.CustomException;
import com.bigdatastudio.common.Utils.R;
import com.bigdatastudio.common.Utils.RedisUtil;
import com.bigdatastudio.auth.utils.TokenUtil;
import com.bigdatastudio.common.entity.Role;
import com.bigdatastudio.common.entity.User;
import com.bigdatastudio.auth.entity.UserDetailsModel;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xiao_jie
 * @since 2022-09-12
 */
@Service
public class AuthServiceImpl extends ServiceImpl<AuthMapper, User> implements IAuthService {

//    获取认证结果
    @Autowired
    private AuthenticationManager authenticationManager;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private TokenUtil tokenUtil;

    @Autowired
    private IRoleService roleService;


    @Override
    public R userLogin(User user, HttpServletRequest request) {
        //初始化返回的信息
        Map<String, String> map = new HashMap<>();
        String uuid = null;
        //将用户名密码封装给认证对象
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getLoginName(), user.getPassword());
        //返回认证结果
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if (Objects.isNull(authenticate)) {
            throw new CustomException(403,"认证失败");
        }
        //存储认证信息
        SecurityContextHolder.getContext().setAuthentication(authenticate);
        //认证成功
        UserDetailsModel principal = (UserDetailsModel) authenticate.getPrincipal();
        //保存到redis,过期时间为一天
        String email = principal.getUser().getEmail();
        redisUtil.set(email, principal,3600*12);
        //生成token返回到前端
        String jwt = tokenUtil.createJWT(principal.getUser().getId().toString(), email);
        // 存储token到集合中
        List<Integer> roles = roleService.listRolesByUserId(TokenUtil.getJwtUser().getId()).stream().map(Role::getId).collect(Collectors.toList());
        String role=roles.toString();
        tokenUtil.putToken(email,jwt);
        map.put("token", jwt);
        map.put("roles",role);
        return R.ok( map, "登录成功！");
    }

    @Override
    public R userLogOut(String token) {
        Claims claims = tokenUtil.parseJWT(token);
        String uuid = claims.getSubject();
        tokenUtil.deleteToken(uuid);
        redisUtil.del(uuid);
        return R.ok("已经退出登录");
    }

}
